package com.pan.insist.controller.admin;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pan.insist.annotation.CacheLock;
import com.pan.insist.annotation.OperateLog;
import com.pan.insist.base.BaseController;
import com.pan.insist.constant.CommonConstant;
import com.pan.insist.constant.OperateConstant;
import com.pan.insist.exception.ValidateException;
import com.pan.insist.exception.ViewException;
import com.pan.insist.model.RoleModel;
import com.pan.insist.service.RoleService;
import com.pan.insist.util.RegexUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Objects;

/**
* <p>
* 角色管理-前端控制器
* </p>
*
* @author kaiji
* @since 2019-08-17
*/
@Log4j2
@Controller
@RequestMapping("/role")
public class RoleController extends BaseController {

    private static final String PAGE_PREFIX = "role/";
    @Resource
    private RoleService roleService;

    @GetMapping("list")
    public String toList() {
        return PAGE_PREFIX + LIST;
    }

    @ResponseBody
    @GetMapping("listJson")
    @OperateLog(operateModule = "角色管理-查询角色列表", operateType = OperateConstant.SELECT, operateDesc = "查询角色列表")
    public JSONObject list(Page<RoleModel> iPage, RoleModel roleModel) {
        QueryWrapper<RoleModel> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(roleModel.getName())) {
            queryWrapper.lambda().like(RoleModel::getName, roleModel.getName().trim());
        }
        if (StringUtils.isNotBlank(roleModel.getCode())) {
            queryWrapper.lambda().like(RoleModel::getCode, roleModel.getCode().trim());
        }
        iPage = roleService.page(iPage, queryWrapper);
        return page2LayTablePage(iPage);
    }

    @GetMapping("/view")
    @CacheLock(prefix = "view")
    @OperateLog(operateModule = "角色管理-查看角色详情", operateType = OperateConstant.VIEW, operateDesc = "查看角色详情")
    public String view(String id, ModelMap modelMap) {
        if (StringUtils.isBlank(id)) {
            throw new ViewException("id不存在");
        }
        RoleModel roleModel;
        roleModel = roleService.getById(id);
        modelMap.put("roleModel", roleModel);
        return PAGE_PREFIX + VIEW;
    }

    @GetMapping("update")
    public String toUpdate(String id, ModelMap modelMap) {
        if (StringUtils.isBlank(id)) {
            throw new ViewException("请选择一条数据！");
        }

        RoleModel roleModel = roleService.getById(id);
        if (roleModel == null) {
            log.info("查询不到数据！");
            throw new ViewException("请选择一条数据！");
        }

        modelMap.put("roleModel", roleModel);
        return PAGE_PREFIX + INPUT;
    }

    @ResponseBody
    @PostMapping("/update")
    @CacheLock(prefix = "role-update")
    @OperateLog(operateModule = "角色管理-修改角色信息", operateType = OperateConstant.UPDATE, operateDesc = "修改角色信息")
    public JSONObject update(@Validated RoleModel roleModel, BindingResult bindingResult) {

        if (bindingResult.hasErrors()) {
            throw new ValidateException(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        // 检测验证数据
        // JSONObject jsonObject = validate(roleModel, CommonConstant.DATA_UPDATE_TYPE);
        /*Integer code = jsonObject.getIntValue(CommonConstant.AjaxCode.CODE);
        if (CommonConstant.AjaxCode.FAIL_CODE.equals(code)) {
            return jsonObject;
        }*/
        JSONObject jsonObject = new JSONObject();
        roleModel.setUpdateDate(LocalDateTime.now());
        roleService.updateById(roleModel);
        jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "修改角色数据成功！");
        jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
        return jsonObject;

    }

    @GetMapping("save")
    public String toSave() {
        return PAGE_PREFIX + INPUT;
    }

    @ResponseBody
    @PostMapping("save")
    @CacheLock(prefix = "save")
    @OperateLog(operateModule = "角色管理-保存角色信息", operateType = OperateConstant.SAVE, operateDesc = "保存角色信息")
    public JSONObject save(RoleModel roleModel) {
        JSONObject jsonObject = validate(roleModel, CommonConstant.DATA_SAVE_TYPE);
        Integer code = jsonObject.getIntValue(CommonConstant.AjaxCode.CODE);
        if (code.equals(CommonConstant.AjaxCode.FAIL_CODE)) {
            return jsonObject;
        }

        jsonObject = new JSONObject();
        try {
            roleModel.setCreateDate(LocalDateTime.now());
            boolean flag = roleService.save(roleModel);
            if (flag) {
                jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "保存角色数据成功！");
            } else {
                jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "保存角色数据失败！");
            }
        } catch (Exception e) {
            log.error("保存角色数据异常！原因：{}", e.getMessage());
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, e.getMessage());
        }
        return jsonObject;
    }

    /**
     * 批量删除
     *
     * @param ids id集合
     */
    @ResponseBody
    @PostMapping("delete")
    @CacheLock(prefix = "delete")
    @OperateLog(operateModule = "角色管理-删除角色信息", operateType = OperateConstant.DELETE, operateDesc = "删除角色信息，可批量删除！")
    public JSONObject delete(String ids) {
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.isBlank(ids)) {
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请至少选择一条数据！");
            return jsonObject;
        }

        try {
            roleService.removeByIds(Arrays.asList(ids.split(CommonConstant.DOC_FLAG)));
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "删除角色数据成功！");
        } catch (Exception e) {
            log.error("删除失败！原因： {}", e.getMessage());
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "删除角色数据失败！");
        }

        return jsonObject;
    }

    /**
     * 进入角色配置权限页面
     *
     * @param id
     *      角色ID主键
     * @param modelMap
     *      request域对象
     * @return  配置页面
     */
    @GetMapping("roleConfig")
    public String toRoleConfig(String id, ModelMap modelMap) {
        RoleModel roleModel = roleService.getById(id);
        if (roleModel == null) {
            throw new RuntimeException("角色数据不存在！");
        }
        modelMap.put("roleId", id);
        return PAGE_PREFIX + "role_config";
    }

    @ResponseBody
    @PostMapping("roleConfig")
    @CacheLock(prefix = "role_config")
    @OperateLog(operateModule = "角色管理-配置角色信息", operateType = OperateConstant.DELETE, operateDesc = "角色配置URL！")
    public JSONObject roleConfig(String purviewIds, String roleId) {
        JSONObject jsonObject = new JSONObject();
        if (StringUtils.isBlank(purviewIds)) {
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请至少选择一个对象！");
            return jsonObject;
        }

        if (StringUtils.isBlank(roleId)) {
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请至少选择一个角色！");
            return jsonObject;
        }
        RoleModel roleMode = roleService.getById(roleId);
        if (roleMode == null) {
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "该角色不存在！");
            return jsonObject;
        }

        try {
            roleService.saveRoleAndPurview(roleId, purviewIds);
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "角色配置权限成功！");
        } catch (Exception e) {
            log.error("配置角色权限失败！原因：{}", e.getMessage());
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "角色配置权限失败！请联系管理员！");
        }
        return jsonObject;

    }


    /**
     * 检测数据是否合格
     *
     * @param roleModel 角色数据对象
     * @param type      1： 修改 2：存储
     */
    protected JSONObject validate(RoleModel roleModel, int type) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
        if (roleModel == null) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "对象不能为空！");
            return jsonObject;
        }

        if (StringUtils.isBlank(roleModel.getName())) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请填写角色名称！");
            return jsonObject;
        }

        // 判断角色名称是否合法
        if (!RegexUtil.matchUsername(roleModel.getName())) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "角色名称不合法！");
            return jsonObject;
        }

        if (StringUtils.isBlank(roleModel.getCode())) {
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请填写角色代码！");
            return jsonObject;
        }

        if (type == CommonConstant.DATA_UPDATE_TYPE) {
            if (StringUtils.isBlank(roleModel.getId())) {
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "请至少选择一个对象数据！");
                return jsonObject;
            }
            // 判断用户是否存在
            RoleModel role = roleService.getById(roleModel.getId());
            if (role == null) {
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "该数据被删除，已经不存在！");
                return jsonObject;
            }
            // 判断角色名称和代码是否存在
            role = roleService.getExistByFilter(roleModel);
            if (role != null) {
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "角色名称或者代码已存在！");
                return jsonObject;
            }

        } else if (type == CommonConstant.DATA_SAVE_TYPE) {
            // 判断用户手机号是否存在
            RoleModel role = roleService.getExistByFilter(roleModel);
            if (role != null) {
                jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "角色名称或者代码已存在！");
                return jsonObject;
            }

        } else {
            jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.FAIL_CODE);
            jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "数据类型错误！");
            return jsonObject;
        }
        jsonObject.put(CommonConstant.AjaxCode.CODE, CommonConstant.AjaxCode.SUCCESS_CODE);
        jsonObject.put(CommonConstant.AjaxCode.MESSAGE, "数据验证成功！");
        return jsonObject;
    }
}
